package co.fitstart.admin.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dynamic;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.utils.DateUtils;

import co.fitstart.admin.dao.CourseRoundDao;
import co.fitstart.admin.dao.CourseRoundResultDao;
import co.fitstart.admin.dao.CourseScheduleDao;
import co.fitstart.admin.dao.InbodyRecordDao;
import co.fitstart.admin.dao.UserDao;
import co.fitstart.admin.service.InbodyRecordService;
import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.round.CourseRoundResult;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.course.schedule.TargetData;
import co.fitstart.entity.user.User;
import co.fitstart.entity.user.bwh.BwhRecord;
import co.fitstart.entity.user.inbody.InbodyData;
import co.fitstart.entity.user.inbody.InbodyRecord;

/**
 * 
 * @author mohanlan
 *
 */
@Service("inbodyRecordService")
public class InbodyRecordServiceImpl implements InbodyRecordService {
    
    private static final Logger logger = LoggerFactory.getLogger(InbodyRecordService.class);
    
    @Dynamic
    private UserDao userDao;
    
    @Dynamic
    private InbodyRecordDao inbodyRecordDao;
    
    @Dynamic
    private CourseScheduleDao courseScheduleDao;
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Dynamic
    private CourseRoundDao courseRoundDao;
    
    @Dynamic
    private CourseRoundResultDao courseRoundResultDao;

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.InbodyRecordService#uploadInbodyData(co.fitstart.entity.user.inbody.InbodyData)
     */
    public void uploadInbodyData(InbodyData inbodyData) {
        User user = userDao.load(inbodyData.getMobile());
        
        // 1. validate delivery record
        
        if(user == null) {  
            
            logger.info("##uploadInbodyData - inbody record this user is not exist with mobile:" + inbodyData.getMobile());
            
            InbodyRecord inbodyRecord = new InbodyRecord(inbodyData);
            genericDaoSupport.save(inbodyRecord);
        
        } else {  // 2. check duplication and import
            InbodyRecord lastInbodyRecord = inbodyRecordDao.load(user);
            
            InbodyRecord inbodyRecord = new InbodyRecord(user, inbodyData);
            
            InbodyRecord originInbodyRecord = inbodyRecordDao.load(inbodyRecord.getMobile(), inbodyRecord.getRecordTime());
            
            if(originInbodyRecord != null) { 
                logger.info("##onUpload - inbody record  in rownum[{}] is a duplicated record.", inbodyData.getMobile(), inbodyData.getName(), inbodyData.getRownum());
            }else {
                
                logger.info("##onUpload - inbody record  create success with rownum[{}]", inbodyData.getMobile(), inbodyData.getName(), inbodyData.getRownum());
                genericDaoSupport.save(inbodyRecord);
                
                if(lastInbodyRecord != null) {
                    BigDecimal b = new BigDecimal(lastInbodyRecord.getBf() - inbodyRecord.getBf());
                    if(b.compareTo(BigDecimal.ZERO) != 0) {
                        TargetData targetData = inbodyRecordDao.loadTargetData();
                        
                        if(targetData != null) {
                            genericDaoSupport.update(targetData.add(b));
                        }
                    }
                }
                
                List<Map<String, Object>> courseRounds = courseRoundDao.listCourseRound(ScheduleStatus.FINISH, user, DateUtils.parseDate(inbodyRecord.getRecordTime().substring(0, 10), "yyyy-MM-dd"));
                if(!courseRounds.isEmpty()) {
                    for(Map<String, Object> courseRound : courseRounds) {
                        Date minOccurDate = (Date)courseRound.get("minOccurDate");
                        Date maxOccurDate = (Date)courseRound.get("maxOccurDate");
                        
                        List<InbodyRecord> inbodyRecords = inbodyRecordDao.listInbodyRecord(user, DateFormatUtils.format(minOccurDate, "yyyy-MM-dd") + " 00:00:00", DateFormatUtils.format(maxOccurDate, "yyyy-MM-dd") + " 23:59:59");
                        
                        if(!inbodyRecords.isEmpty()) {
                            CourseRoundResult courseRoundResult = courseRoundResultDao.load((CourseRound)courseRound.get("courseRound"));
                            if(courseRoundResult == null) {
                                genericDaoSupport.save(new CourseRoundResult((CourseRound)courseRound.get("courseRound"), inbodyRecords.get(inbodyRecords.size() - 1), inbodyRecords.get(0)));
                            } else {
                                genericDaoSupport.update(courseRoundResult.edit(inbodyRecords.get(inbodyRecords.size() - 1), inbodyRecords.get(0)));
                            }
                        }
                    }
                }
            }
        }
        
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.InbodyRecordService#listInbodyRecoreds(co.fitstart.entity.course.round.CourseRound)
     */
    public List<InbodyRecord> listInbodyRecoreds(CourseRound courseRound) {
        
        List<InbodyRecord> inbodyRecords = new ArrayList<InbodyRecord>();
        
       
        
        Map<String, String> times = this.getTimes(courseRound);
        
        String start = times.get("startTime");
        String end = times.get("endTime");
        logger.info("student  [{}] start [{}] end [{}]",courseRound.getStudent().getUser(),start,end);
        if(MapUtils.isNotEmpty(times)) {
            inbodyRecords = inbodyRecordDao.listInbodyRecord(courseRound.getStudent().getUser(), times.get("startTime"), times.get("endTime"));
        }
        
        return inbodyRecords;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.InbodyRecordService#listBwhRecords(co.fitstart.entity.course.round.CourseRound)
     */
    public List<BwhRecord> listBwhRecords(CourseRound courseRound) {
        
//        List<BwhRecord> bwhRecords = new ArrayList<BwhRecord>();
//        
//        Map<String, String> times = this.getTimes(courseRound);
//        if(MapUtils.isNotEmpty(times)) {
//            bwhRecords = inbodyRecordDao.listBwhRecord(courseRound.getStudent().getUser(), times.get("startTime"), times.get("endTime"));
//        }
    	List<BwhRecord> bwhRecords = inbodyRecordDao.listBwhRecord(courseRound);
        
        return bwhRecords;
        
    }
    
    /**
     * 
     * @param courseRound
     * @return
     */
    private Map<String, String> getTimes(CourseRound courseRound) {
        Map<String, String> times = new HashMap<String, String>();
        
        List<CourseSchedule> courseSchedules = courseScheduleDao.listCourseSchedule(courseRound);
               
        if(!courseSchedules.isEmpty()) { 
            times.put("startTime", DateFormatUtils.format(courseSchedules.get(courseSchedules.size()-1).getOccurDate(), "yyyy-MM-dd") + " 00:00:00");
            times.put("endTime", DateFormatUtils.format(courseSchedules.get(0).getOccurDate(), "yyyy-MM-dd") + " 23:23:59");
        }
        
        return times;
    }
    
}
